import React, { useState, useEffect, useRef } from "react";
import {
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  TextField,
  Button,
  Box,
  ListItemIcon,
  ListItemText,
  ThemeProvider,
  createTheme,
  CssBaseline,
} from "@mui/material";
import ContextMenu from "./components/ContextMenu";
import BottomBar from "./components/BottomBar";
import ToolBar from "./components/ToolBar";
import { invoke } from "@tauri-apps/api/core";
import { open } from "@tauri-apps/plugin-dialog";
import { listen } from "@tauri-apps/api/event";
import { writeText } from "@tauri-apps/plugin-clipboard-manager";
import Sidebar from "./components/Sidebar";
import { Check } from "@mui/icons-material";
import DirectorySelect from "./components/DirectorySelect";
import Settings from "./components/Settings";
import HttpSettings from "./components/HttpSettings";
import ExitConfirmDialog from "./components/ExitConfirmDialog";
import DownloadTable from "./components/DownloadTable";
import Alert from "@mui/material/Alert";
import Snackbar from "@mui/material/Snackbar";
import Divider from "@mui/material/Divider";
import NewDownloadDialog from "./components/NewDownloadDialog";

function App() {
  const [downloads, setDownloads] = useState([]);
  const [selectedItems, setSelectedItems] = useState(new Set());
  const [contextMenu, setContextMenu] = useState(null);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [url, setUrl] = useState("");
  const [directory, setDirectory] = useState("");
  const [downloadSpeeds, setDownloadSpeeds] = useState({});
  const speedTrackerRef = useRef({}); // 用于跨渲染周期跟踪下载速度
  const [sortBy, setSortBy] = useState("name"); // 默认按文件名排序
  const [filter, setFilter] = useState("downloading"); // 默认显示下载中的列表
  const [isSidebarOpen, setIsSidebarOpen] = useState(true);
  const [currentView, setCurrentView] = useState("downloading"); // 用于控制当前显示的视图
  const [settings, setSettings] = useState({
    language: "简体中文",
    theme: "浅色",
    page_title: "${downspeed}, ${upspeed} - ${title}",
    page_title_update_interval: 5,
    status_update_interval: 1,
    task_info_update_interval: 1,
    task_delete_confirm: "启用",
  });
  const [exitDialogOpen, setExitDialogOpen] = useState(false);

  // 创建主题
  const theme = createTheme({
    palette: {
      mode: settings.theme === "深色" ? "dark" : "light",
    },
  });

  // 更新页面标题
  useEffect(() => {
    const updatePageTitle = () => {
      const speed = Object.values(downloadSpeeds)[0]?.speed || 0;
      const title = settings.page_title
        .replace("${downspeed}", formatSpeed(speed))
        .replace("${upspeed}", "0 B/s")
        .replace("${title}", "红岸下载工具");
      document.title = title;
    };

    const interval = setInterval(
      updatePageTitle,
      settings.page_title_update_interval * 1000
    );
    updatePageTitle(); // 立即更新一次

    return () => clearInterval(interval);
  }, [
    settings.page_title,
    settings.page_title_update_interval,
    downloadSpeeds,
  ]);

  // 读取配置和会话数据
  useEffect(() => {
    invoke("get_config").then((config) => {
      if (config) {
        setSettings(config);
      }
    });

    invoke("get_session_data").then((list) => {
      if (list && list.downloads) {
        setDownloads(list.downloads);
      }
    });
  }, []);

  useEffect(() => {
    const unlisten = listen("download_progress", (event) => {
      const {
        id,
        progress,
        total_size,
        status,
        downloaded_size,
        thread_progress,
      } = event.payload;

      setDownloads((prevDownloads) => {
        const updatedDownloads = prevDownloads.map((download) =>
          download.id === id
            ? {
                ...download,
                progress,
                status: status,
                size:
                  total_size > 0
                    ? `${(total_size / 1024 / 1024).toFixed(2)} MB`
                    : "未知",
                total_bytes: total_size,
                thread_progress: thread_progress || [],
              }
            : download
        );

        // 如果当前任务完成且正在显示下载中的列表，自动更新过滤状态
        const completedDownload = updatedDownloads.find(
          (d) => d.id === id && d.status === "Completed"
        );
        if (completedDownload && filter === "downloading") {
          // 保持在下载中的列表视图
          return updatedDownloads;
        }

        return updatedDownloads;
      });

      const now = Date.now();
      const tracker = speedTrackerRef.current;

      if (!tracker[id]) {
        tracker[id] = {
          time: now,
          size: downloaded_size,
          speed: 0,
          accumulatedSize: 0,
          lastSpeedUpdate: now,
          remainingTime: null, // 添加剩余时间字段
        };
        return;
      }

      const prevData = tracker[id];
      const timeDiff = now - prevData.lastSpeedUpdate;

      // 累积下载量
      prevData.accumulatedSize += downloaded_size - prevData.size;
      prevData.size = downloaded_size;
      prevData.time = now;

      if (timeDiff >= 1000) {
        // 使用累积的下载量计算速度
        const speedBytesPerSec = (prevData.accumulatedSize / timeDiff) * 1000;

        const newSpeed = prevData.speed
          ? prevData.speed * 0.7 + speedBytesPerSec * 0.3
          : speedBytesPerSec;

        // 计算剩余时间
        const remainingTime =
          total_size && newSpeed > 0
            ? (total_size - downloaded_size) / newSpeed
            : null;

        // 更新跟踪器
        tracker[id] = {
          ...prevData,
          lastSpeedUpdate: now,
          accumulatedSize: 0,
          speed: newSpeed,
          remainingTime, // 添加剩余时间
        };

        // 更新显示的速度和剩余时间
        setDownloadSpeeds((prevSpeeds) => ({
          ...prevSpeeds,
          [id]: tracker[id],
        }));
      }
    });

    return () => {
      unlisten.then((f) => f());
    };
  }, []);

  const usePrevious = (value) => {
    const ref = useRef();
    useEffect(() => {
      ref.current = value;
    });
    return ref.current;
  };

  const prevDownloads = usePrevious(downloads);

  useEffect(() => {
    const hasStatusChanged = downloads.some((download, index) => {
      return download.status !== prevDownloads[index]?.status;
    });

    if (hasStatusChanged) {
      invoke("update_session_data", { downloads })
        .then((response) => console.log(response))
        .catch((err) => console.error("更新会话数据失败:", err));
    }

    const handleWindowCloseRequested = () => {
      const hasDownloadingTasks = downloads.some(
        (d) => d.status === "Downloading"
      );
      if (hasDownloadingTasks) {
        setExitDialogOpen(true);
      } else {
        invoke("close_window");
      }
    };

    const unlisten = listen(
      "window-close-requested",
      handleWindowCloseRequested
    );

    return () => {
      unlisten.then((f) => f());
    };
  }, [downloads]);

  const handleExitConfirm = async () => {
    // 暂停所有正在下载的任务
    const downloadingTasks = downloads.filter(
      (d) => d.status === "Downloading"
    );
    for (const task of downloadingTasks) {
      await invoke("pause_download", { id: task.id });
    }
    // 关闭对话框
    setExitDialogOpen(false);
    // 关闭程序
    await invoke("close_window");
  };

  const handleExitCancel = () => {
    setExitDialogOpen(false);
  };

  const handleContextMenu = (event, downloadId) => {
    event.preventDefault();
    setContextMenu({
      mouseX: event.clientX,
      mouseY: event.clientY,
      downloadId,
    });
  };

  const handleCloseContextMenu = () => {
    setContextMenu(null);
  };

  const handleCheckboxChange = (downloadId) => {
    setSelectedItems((prev) => {
      const newSelected = new Set(prev);
      if (newSelected.has(downloadId)) {
        newSelected.delete(downloadId);
      } else {
        newSelected.add(downloadId);
      }
      return newSelected;
    });
  };

  const handleSelectAll = () => {
    if (selectedItems.size === downloads.length) {
      setSelectedItems(new Set());
    } else {
      setSelectedItems(new Set(downloads.map((d) => d.id)));
    }
    handleCloseContextMenu();
  };

  const handlePauseTask = async (ids) => {
    try {
      if (Array.isArray(ids)) {
        for (const id of ids) {
          await invoke("pause_download", { id });
        }
      } else {
        await invoke("pause_download", { id: ids });
      }
      handleCloseContextMenu();
    } catch (error) {
      console.error("暂停下载失败:", error);
    }
  };

  const handleResumeTask = async (ids) => {
    try {
      if (Array.isArray(ids)) {
        for (const id of ids) {
          await invoke("resume_download", { id });
        }
      } else {
        await invoke("resume_download", { id: ids });
      }
      handleCloseContextMenu();
    } catch (error) {
      console.error("恢复下载失败:", error);
    }
  };

  const handleDeleteTask = async (ids) => {
    try {
      if (Array.isArray(ids)) {
        for (const id of ids) {
          await invoke("delete_download", { id });
        }
      } else {
        await invoke("delete_download", { id: ids });
      }
      handleCloseContextMenu();
    } catch (error) {
      console.error("删除任务失败:", error);
    }
  };

  const handleCopyLink = async (id) => {
    const download = downloads.find((d) => d.id === id);
    if (download) {
      await writeText(download.url);
      setSnackbar({
        open: true,
        message: "拷贝到剪切板成功！",
        severity: "success",
      });
      handleCloseContextMenu();
    }
  };

  const openDialog = () => setDialogOpen(true);
  const closeDialog = () => setDialogOpen(false);

  const selectDirectory = async () => {
    const selectedPath = await open({ directory: true });
    if (selectedPath) setDirectory(selectedPath);
  };

  async function addDownload() {
    openDialog();
  }

  // 在其他 state 声明后添加
  const [snackbar, setSnackbar] = useState({
    open: false,
    message: "",
    severity: "error",
  });

  const handleSnackbarClose = (event, reason) => {
    if (reason === "clickaway") {
      return;
    }
    setSnackbar((prev) => ({
      ...prev,
      open: false,
    }));
  };

  const handleDownload = async ({ url, directory }) => {
    if (!url || !directory) {
      setSnackbar({
        open: true,
        message: "请填写完整的下载信息！",
        severity: "warning",
      });
      return;
    }

    // 检查 URL 格式并获取协议
    let protocol;
    try {
      const urlObj = new URL(url);
      protocol = urlObj.protocol.toLowerCase().replace(":", "");

      // 检查是否支持的协议
      if (!["http", "https", "ftp", "sftp"].includes(protocol)) {
        setSnackbar({
          open: true,
          message: `不支持的协议：${protocol}，仅支持 HTTP、HTTPS、FTP 和 SFTP 协议`,
          severity: "error",
        });
        return;
      }
    } catch (error) {
      setSnackbar({
        open: true,
        message: "下载地址格式不正确",
        severity: "error",
      });
      return;
    }

    const file_name = url.substring(url.lastIndexOf("/") + 1);
    const id = downloads.length + 1;

    const newDownload = {
      id: id,
      file_name: file_name,
      path: directory,
      url: url,
      size: "未知",
      status: "Downloading",
      progress: 0,
      protocol: protocol,
    };

    try {
      if (
        protocol === "ftp" ||
        protocol === "sftp" ||
        protocol === "http" ||
        protocol === "https"
      ) {
        const result = await invoke("create_download_task", {
          id,
          url,
          file: file_name,
          path: directory,
          protocol,
        });

        if (result !== "任务创建成功") {
          setSnackbar({
            open: true,
            message: "创建下载任务失败：" + result,
            severity: "error",
          });
          return;
        }
      }

      setDownloads((prevDownloads) => {
        const newDownloads = [...prevDownloads, newDownload];
        return newDownloads;
      });

      // 开始下载
      if (
        protocol === "ftp" ||
        protocol === "sftp" ||
        protocol === "http" ||
        protocol === "https"
      ) {
        await invoke("start_download", { id });
      }
    } catch (error) {
      setSnackbar({
        open: true,
        message: "创建下载任务失败：" + error,
        severity: "error",
      });
    }
  };

  const formatSpeed = (bytesPerSec) => {
    if (!bytesPerSec) return "0 B/s";
    const units = ["B/s", "KB/s", "MB/s", "GB/s"];
    let size = bytesPerSec;
    let unitIndex = 0;

    while (size >= 1024 && unitIndex < units.length - 1) {
      size /= 1024;
      unitIndex++;
    }

    return `${size.toFixed(2)} ${units[unitIndex]}`;
  };

  const formatRemainingTime = (seconds, status) => {
    if (status === "Completed") return "0秒";
    if (!seconds || seconds === Infinity) return "未知";
    if (seconds < 60) return `${Math.ceil(seconds)}秒`;

    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const remainingSeconds = Math.ceil(seconds % 60);

    let result = "";
    if (hours > 0) result += `${hours}小时`;
    if (minutes > 0) result += `${minutes}分`;
    if (remainingSeconds > 0) result += `${remainingSeconds}秒`;

    return result;
  };

  const getStatusText = (status) => {
    switch (status) {
      case "Completed":
        return "已完成";
      case "Downloading":
        return "下载中";
      case "Paused":
        return "已暂停";
      case "Pending":
        return "等待中";
      case "Error":
        return "错误";
      default:
        return status;
    }
  };

  const downloadStats = {
    downloading: downloads.filter((d) => d.status === "Downloading").length,
    paused: downloads.filter((d) => d.status === "Paused").length,
    completed: downloads.filter(
      (d) => d.status === "Completed" || d.status === "Error"
    ).length,
  };

  const getCurrentDownload = () => {
    if (!contextMenu) return null;
    return downloads.find((d) => d.id === contextMenu.downloadId);
  };

  const handleSortMenuOpen = (event) => {
    setSortMenuAnchor(event.currentTarget);
  };

  const handleSortMenuClose = () => {
    setSortMenuAnchor(null);
    handleCloseContextMenu();
  };

  const handleSortSelect = (value) => {
    setSortBy(value);
    handleSortMenuClose();
    handleCloseContextMenu();
  };

  const filteredDownloads = downloads.filter((download) => {
    if (filter === "all") return true;
    if (filter === "downloading") return download.status === "Downloading";
    if (filter === "paused") return download.status === "Paused";
    if (filter === "completed")
      return download.status === "Completed" || download.status === "Error";
    return false;
  });

  // 更新配置的处理函数
  const handleSettingsChange = async (newSettings) => {
    setSettings(newSettings);
    try {
      // 转换布尔值设置
      const convertedSettings = {
        ...newSettings,
        "check-certificate": newSettings["check-certificate"] === "是",
        "http-accept-gzip": newSettings["http-accept-gzip"] === "是",
        "http-auth-challenge": newSettings["http-auth-challenge"] === "是",
        "http-pipelining": newSettings["http-pipelining"] === "是",
      };
      await invoke("update_config", { config: convertedSettings });
    } catch (error) {
      console.error("保存配置失败:", error);
      setSnackbar({
        open: true,
        message: "保存配置失败：" + error,
        severity: "error",
      });
    }
  };

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <Box sx={{ display: "column" }}>
        <ToolBar
          onAdd={addDownload}
          selectedItems={selectedItems}
          onDownload={handleResumeTask}
          onPause={handlePauseTask}
          onDelete={handleDeleteTask}
          onSelectAll={handleSelectAll}
          onSort={handleSortSelect}
          onToggleSidebar={() => setIsSidebarOpen(!isSidebarOpen)}
        />
        {currentView === "downloading" && (
          <DownloadTable
            downloads={downloads.filter((d) => {
              switch (filter) {
                case "downloading":
                  return d.status === "Downloading";
                case "paused":
                  return d.status === "Paused";
                case "completed":
                  return d.status === "Completed" || d.status === "Error";
                default:
                  return true;
              }
            })}
            selectedItems={selectedItems}
            onSelectAll={handleSelectAll}
            onSelectItem={handleCheckboxChange}
            onRowClick={handleCheckboxChange}
            onContextMenu={handleContextMenu}
            getStatusText={getStatusText}
            formatSpeed={formatSpeed}
            formatRemainingTime={formatRemainingTime}
            downloadSpeeds={downloadSpeeds}
          />
        )}
        {currentView === "basic-settings" && (
          <Settings settings={settings} onSettingsChange={setSettings} />
        )}
        {currentView === "http-settings" && (
          <HttpSettings settings={settings} onSettingsChange={setSettings} />
        )}
        <Sidebar
          downloadStats={downloadStats}
          onFilterChange={setFilter}
          onViewChange={setCurrentView}
          isSidebarOpen={isSidebarOpen}
        />
      </Box>

      <NewDownloadDialog
        open={dialogOpen}
        onClose={closeDialog}
        onDownload={handleDownload}
      />

      <ContextMenu
        contextMenu={contextMenu}
        onClose={handleCloseContextMenu}
        download={getCurrentDownload()}
        onPauseTask={handlePauseTask}
        onResumeTask={handleResumeTask}
        onDeleteTask={handleDeleteTask}
        onCopyLink={handleCopyLink}
        onSelectAll={handleSelectAll}
        onSortSelect={setSortBy}
        isAllSelected={selectedItems.size === downloads.length}
        sortBy={sortBy}
        onContextMenu={handleContextMenu}
      />

      <ExitConfirmDialog
        open={exitDialogOpen}
        onConfirm={handleExitConfirm}
        onCancel={handleExitCancel}
      />

      <Snackbar
        open={snackbar.open}
        autoHideDuration={6000}
        onClose={handleSnackbarClose}
      >
        <Alert
          onClose={handleSnackbarClose}
          severity={snackbar.severity}
          sx={{ width: "100%" }}
        >
          {snackbar.message}
        </Alert>
      </Snackbar>
    </ThemeProvider>
  );
}

export default App;
